﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;

namespace Ec.NETCoreFramework.Common.Core.Helpers
{
    public static partial class Json
    {
        /// <summary>
        /// 将Json字符串转换为对象
        /// </summary>
        /// <param name="json">Json字符串</param>
        public static T ToObject<T>(string json)
        {
            if (string.IsNullOrWhiteSpace(json))
                return default(T);

            return JsonConvert.DeserializeObject<T>(json);
        }

        public static object ToObject(string json, System.Type type)
        {
            if (string.IsNullOrWhiteSpace(json))
                return null;
            return JsonConvert.DeserializeObject(json, type);
        }

        /// <summary>
        /// 将对象转换为Json字符串
        /// </summary>
        /// <param name="target">目标对象</param>
        /// <param name="isConvertToSingleQuotes">是否将双引号转成单引号</param>
        public static string ToJson(object target, bool isConvertToSingleQuotes = false)
        {
            if (target == null)
                return string.Empty;
            var result = JsonConvert.SerializeObject(target);
            if (isConvertToSingleQuotes)
                result = result.Replace("\"", "'");
            return result;
        }
        #region 字符串转换为Xml对象
        /// <summary>
        /// json字符串转换为Xml对象
        /// </summary>
        /// <param name="sJson">The s json.</param>
        /// <returns></returns>
        public static XmlDocument JsonToXml(string sJson)
        {

            var Dic = JsonConvert.DeserializeObject(sJson) as JObject;
            XmlDocument doc = new XmlDocument();
            XmlDeclaration xmlDec;
            xmlDec = doc.CreateXmlDeclaration("1.0", "utf-8", "yes");
            doc.InsertBefore(xmlDec, doc.DocumentElement);
            XmlElement nRoot = doc.CreateElement("root");
            doc.AppendChild(nRoot);
            JobjectToXml(nRoot, Dic);
            return doc;
        }
        /// <summary>
        /// JObjectToXml
        /// </summary>
        /// <param name="jobject"></param>
        /// <param name="nodeName"></param>
        /// <returns></returns>
        public static XmlElement JsonToXml(JObject jobject, string nodeName)
        {


            XmlDocument doc = new XmlDocument();
            XmlDeclaration xmlDec;
            xmlDec = doc.CreateXmlDeclaration("1.0", "utf-8", "yes");
            doc.InsertBefore(xmlDec, doc.DocumentElement);
            XmlElement nRoot = doc.CreateElement(nodeName);
            doc.AppendChild(nRoot);
            JobjectToXml(nRoot, jobject);
            return nRoot;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="node"></param>
        /// <param name="Source"></param>
        private static void JobjectToXml(XmlElement node, JObject Source)
        {
            try
            {
                foreach (var item in Source)
                {
                    XmlElement element = node.OwnerDocument.CreateElement(item.Key);
                    JobjectToXml(element, item);
                    node.AppendChild(element);
                }
            }
            catch (Exception ex)
            {
                LoggerHelper.Instance.Error(ex.Message);


            }

        }
        /// <summary>
        /// Keys the value2 XML.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="Source">The source.</param>
        private static void JobjectToXml(XmlElement node, KeyValuePair<string, JToken?> Source)
        {
            var kValue = Source.Value;
            if (kValue.GetType() == typeof(JObject))
            {
                foreach (var item in kValue as JObject)
                {
                    XmlElement element = node.OwnerDocument.CreateElement(item.Key);
                    JobjectToXml(element, item);
                    node.AppendChild(element);
                }
            }
            else if (kValue.GetType() == typeof(JArray))
            {
                var o = kValue as JArray;
                if (o.Count == 0)
                {
                    return;
                }
                if (o.First.GetType() == typeof(JValue))
                {
                    CreateArrayValue(node, o, Source.Key);
                }
                else
                {
                    foreach (JObject obj in o)
                    {
                        XmlElement xitem = node.OwnerDocument.CreateElement(Source.Key);
                        JobjectToXml(xitem, obj);
                        node.AppendChild(xitem);
                    }
                }

            }
            else
            {
                var v = kValue.ToString();
                CreateValue(node, v);
            }
        }
        public static void CreateArrayValue(XmlElement node, JArray o,string key)
        {
            foreach (JValue obj in o)
            {
                XmlElement jvalue = node.OwnerDocument.CreateElement(key);
                CreateValue(jvalue, obj.ToString());
                node.AppendChild(jvalue);
            }
        }
        private static void CreateValue(XmlElement node, string v)
        {

            var _regex = new Regex(@"^[-_a-zA-Z0-9|]{0,}$", RegexOptions.Compiled);
            if (!_regex.IsMatch(v))
            {
                var text = node.OwnerDocument.CreateCDataSection(v);

                node.AppendChild(text);
            }
            else
            {
                var text = node.OwnerDocument.CreateTextNode(v);

                node.AppendChild(text);
            }
        }
        #endregion
    }
}
